<?php
	if (!class_exists('MyDebuger'))
		die('Se requiere de la clase \'MyDebuger\' para utilizar la clase \'MEMStats\'');
		
	final class MEMStats extends MyDebuger {
		/* Estados de las memorias RAM y SWAP */
		private $results	= Array();
		/* Comando de ejecucion */
		private $command	= 'free -ob';
		
		/* constructor */
		public function __construct($nombre = 'MEMStats') {
			/* creamos el padre */
			parent::__construct($nombre);
		}
		
		/* destructor */
		public function __destruct() {
			/* mostramos un mensaje */
			$this->show('Desconectando de la memoria..', False);
			/* matamos el padre */
			parent::__destruct();
			/* Mostramos OK */
			$this->showOK();
		}
		
		public function getData($type = 'ram') {
			try {
				/* cargamos el estado actual de la memoria */
				$this->checkLoad();
				/* verificamos que el valor solicitado existe */
				$this->verificarSolicitud($type);
				/* retornamos el valor solicitado */
				return $this->results[$type];
			} catch (MyException $e) {
				/* si se produjo una excepcion la manejamos con el metodo 'show' */
				$this->show($e->getMensaje($this->html));
			}
		}
		
		private function verificarSolicitud($type) {
			/* mostramos un mensaje */
			$this->show('Verificando solicitud..', False);
			/* verificamos si existe la clave */
			if (!array_key_exists($type, $this->results))
				/* si no existe finalizamos con un error */
				$this->newException('Opcion incorrecta');
			/* mostramos OK al mensaje */
			$this->showOK();
		}
		
		private function checkLoad() {
			/* mostramos un mensaje */
			$this->show('Obteniendo datos', False); $this->show('..');
			/* obtenemos los datos actuales de la memoria */
			$this->getMemData();
			/* mostramos un mensaje */
			$this->show('Procesando datos', False); $this->show('..');
			/* procesamos los datos */
			$this->processData();
		}
		
		private function getMemData() {
			/* vaciamos los datos actuales */
			$this->emptyData();
			/* ejecutamos el comando para obtener los datos */
			$this->ejecutarComando();
			/* limpiamos los resultados */
			$this->cleanResults();
		}
		
		private function emptyData() {
			/* vaciamos los datos actuales (si existieren) */
			$this->results = Array();
		}
		
		private function ejecutarComando() {
			/* mostramos un mensaje */
			$this->show('Ejecutando comando..', False);
			/* ejecutamos el comando para obtener los datos */
			exec($this->command, $this->results);
			/* ok al mensaje */
			$this->showOK();
		}
		
		private function cleanResults() {
			/* mostramos un mensaje */
			$this->show('Limpiando resultados..', False);
			/* eliminamos los titulos que no son necesarios */
			unset($this->results[0]);
			/* recorremos las lineas de resultado */
			for ($i = 1; $i < 3; $i++)
				/* limpiamos las lineas de resultados */
				$this->results[$i] = $this->clean($this->results[$i]);
			/* ok al mensaje */
			$this->showOK();
		}
		
		private function clean($data) {
			/* buscamos espacios dobles */
			while (strstr($data, '  '))
				/* eliminamos los espacios dobles */
				$data = str_replace('  ', ' ', $data);
			/* retornamos los resultados limpios */
			return $data;
		}
		
		private function processData() {
			/* ordenamos los valores */
			$this->ordenarValores();
			/* rearmamos los resultados */
			$this->reordenarResultados();
			/* eliminamos los datos inncesesarios */
			$this->eliminarInnecesarios();
		}
		
		private function ordenarValores() {
			/* mostramos un mensaje */
			$this->show('Asignando valores..', False);
			/* separamos los valores */
			$this->results[1] = explode(' ', $this->results[1]);
			$this->results[2] = explode(' ', $this->results[2]);
			/* ok al mensaje */
			$this->showOK();
		}
		
		private function reordenarResultados() {
			/* mostramos un mensaje */
			$this->show('Reordenando resultados..', False);
			/* almacenamos los valores de la RAM */
			$this->almacenar(1, 'ram');
			/* almacenamos los valores de la SWAP */
			$this->almacenar(2, 'swap');
			/* OK al mensaje */
			$this->showOK();
		}
		
		private function almacenar($type, $title) {
			/* almacenamos el tamano total de la memoria */
			$this->save($type, $title, 'total', 1);
			/* almacenamos el tamano en uso */
			$this->save($type, $title, 'used', 2);
			/* almacenamos el tamano libre */
			$this->save($type, $title, 'free', 3);
			/* almacenamos otros valores */
			$this->saveAnothers($type, $title, Array(
				4 => 'shared',
				5 => 'buffers',
				6 => 'cached'
			));
		}
		
		private function save($type, $title, $sub, $value) {
			/* almacenamos el resultado */
			$this->results[$title][$sub] = $this->results[$type][$value];
		}
		
		private function saveAnothers($type, $title, $titles) {
			/* recorremos los demas valores */
			foreach ($titles AS $valor => $titulo) {
				/* verificamos si existen los demas valores a almacenar */
				if (isset($this->results[$type][$valor])) {
					/* almacenamos los valores */
					$this->save($type, $title, $titulo, $valor);
					/* restamos del uso total */
					$this->results[$title]['used'] -= $this->results[$title][$titulo];
				}
			}
		}
		
		private function eliminarInnecesarios() {
			/* eliminamos los dos indices que no utilizamos */
			unset($this->results[1], $this->results[2]);
		}
	}
?>